﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;

namespace Marmat.Forms
{
    [Editor("Marmat.Forms.Design.TabControlUITypeEditor", typeof(UITypeEditor))]
    public class TabPageCollection : IList, ICollection<TabPage>
    {
        private readonly TabControl tabControl;
        private readonly List<TabPage> _collection;

        internal TabPageCollection(TabControl tabControl)
        {
            this.tabControl = tabControl;
            this._collection = new List<TabPage>();
        }

        public TabPage Add()
        {
            return this.Add($"tabPage{this.Count + 1}");
        }

        public TabPage Add(string text)
        {
            var tabPage = this.CreatePage();
            if ((text ?? "") != (string.Empty ?? ""))
            {
                tabPage.Text = text;
            }

            this.Add(tabPage);
            return tabPage;
        }

        public void Add(TabPage item)
        {
            if (!this.Contains(item))
            {
                item.Dock = DockStyle.Fill;
                item.ImageList = this.tabControl.ImageList;
                this.tabControl.Controls.Add(item);
                if (this.tabControl.Container is object)
                {
                    this.tabControl.Container.Add(item);
                }

                if (this.tabControl.SelectedTab is object)
                {
                    this.tabControl.SelectedTab.BringToFront();
                }

                this._collection.Add(item);
                this.tabControl.Invalidate();
            }
        }

        protected virtual TabPage CreatePage()
        {
            return new TabPage();
        }

        /// <summary>
        /// 获取或设置指定索引处的元素。
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public TabPage this[int index]
        {
            get
            {
                return this._collection[index];
            }
        }

        object IList.this[int index]
        {
            get => this._collection[index];
            set => throw new NotImplementedException();
        }

        bool IList.IsReadOnly => ((IList)this._collection).IsReadOnly;
        bool ICollection<TabPage>.IsReadOnly => ((ICollection<TabPage>)this._collection).IsReadOnly;

        bool IList.IsFixedSize
        {
            get
            {
                return ((IList)this._collection).IsFixedSize;
            }
        }

        public int Count
        {
            get
            {
                return this._collection.Count;
            }
        }

        object ICollection.SyncRoot
        {
            get
            {
                return ((ICollection)this._collection).SyncRoot;
            }
        }

        bool ICollection.IsSynchronized
        {
            get
            {
                return ((ICollection)this._collection).IsSynchronized;
            }
        }

        public bool Contains(TabPage item)
        {
            return this._collection.Contains(item);
        }

        public bool Remove(TabPage item)
        {
            bool result = false;
            if (this.Contains(item))
            {
                this.tabControl.Controls.Remove(item);
                if (this.tabControl.Container is object)
                    this.tabControl.Container.Remove(item);
                result = this._collection.Remove(item);
            }

            return result;
        }

        int IList.Add(object value)
        {
            return ((IList)this._collection).Add(value);
        }

        bool IList.Contains(object value)
        {
            return ((IList)this._collection).Contains(value);
        }


        public void Clear()
        {
            if (this.tabControl.Container is object)
            {
                foreach (IComponent component in this._collection)
                    this.tabControl.Container.Remove(component);
            }
            this.tabControl.Controls.Clear();
            this._collection.Clear();
        }

        public int IndexOf(object value)
        {
            return ((IList)this._collection).IndexOf(value);
        }

        public int IList_IndexOf(object value) => IndexOf(value);

        public int IndexOf(TabPage value)
        {
            return ((IList)this._collection).IndexOf(value);
        }

        void IList.Insert(int index, object value)
        {
            ((IList)this._collection).Insert(index, value);
        }

        public void Insert(int index, TabPage value)
        {
            ((IList)this._collection).Insert(index, value);
        }

        void IList.Remove(object value)
        {
            TabPage tabPage = (TabPage)value;
            this.Remove(tabPage);
        }

        void IList.RemoveAt(int index)
        {
            var tabPage = this[index];
            this.Remove(tabPage);
        }

        void ICollection.CopyTo(Array array, int index)
        {
            ((ICollection)this._collection).CopyTo(array, index);
        }

        public void CopyTo(TabPage[] array, int arrayIndex)
        {
            ((ICollection<TabPage>)this._collection).CopyTo(array, arrayIndex);
        }

        public IEnumerator<TabPage> GetEnumerator()
        {
            return ((IEnumerable<TabPage>)this._collection).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this._collection.GetEnumerator();
        }
    }
}